package cn.shengchao.ycbdc.acl.adapters.repositories;

import cn.hutool.core.collection.CollUtil;
import cn.shengchao.base.lock.DistributedLock;
import cn.shengchao.base.lock.ZLock;
import cn.shengchao.base.utils.RandomPhoneGenerator;
import cn.shengchao.ycbdc.acl.ports.repositories.IProductThirdYcbdcUserOrderRepository;
import cn.shengchao.ycbdc.infrastructure.dao.ProductThirdYcbdcUserOrderDao;
import cn.shengchao.ycbdc.infrastructure.dao.po.ProductThirdYcbdcUserOrder;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.continew.starter.core.validation.CheckUtils;
import top.continew.starter.extension.crud.model.entity.BaseDO;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @program: examstarapi
 * @description: 忆成英语订单记录
 * @author: Xiong weiqiang
 * @create: 2025-06-05 11:37
 */
@Service
public class ProductThirdYcbdcUserOrderRepository implements IProductThirdYcbdcUserOrderRepository {
    @Autowired
    private ProductThirdYcbdcUserOrderDao productThirdYcbdcUserOrderDao;
    @Autowired
    private DistributedLock distributedLock;

    @Override
    public void newOrder(ProductThirdYcbdcUserOrder order) {
        //只保留最新的订单和日期备用
        productThirdYcbdcUserOrderDao.update(Wrappers.lambdaUpdate(ProductThirdYcbdcUserOrder.class)
                .eq(ProductThirdYcbdcUserOrder::getUserId, order.getUserId())
                .eq(ProductThirdYcbdcUserOrder::getDataStatus, 1)
                .set(ProductThirdYcbdcUserOrder::getDataStatus, 2)
        );
        productThirdYcbdcUserOrderDao.insert(order);
    }
    @Override
    public List<ProductThirdYcbdcUserOrder> queryByWrapper(Wrapper<ProductThirdYcbdcUserOrder> wrapper){
        return productThirdYcbdcUserOrderDao.selectList(wrapper);
    }

    @Override
    public String getPhoneForUserId(Long userId) {
        try {
            String phone= getMobile(userId);
            if (phone==null){
                return getPhoneForUserId(userId);
            }else {
                return phone;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private  String getMobile(Long userId) throws  Exception{
        // 使用分布式锁确保同一订单退款操作的幂等性
        String lockKey = "YCBDC_USER_RANDOM_PHONE:" + userId;
        ZLock zLock = null;
        try {
            // 尝试获取锁，等待最多3秒，锁定30秒
            zLock = distributedLock.tryLock(lockKey, 3,  TimeUnit.SECONDS);
            CheckUtils.throwIf(zLock == null, "获取手机号，请稍后重试");
            List<ProductThirdYcbdcUserOrder> list=productThirdYcbdcUserOrderDao.selectList(Wrappers.lambdaQuery(ProductThirdYcbdcUserOrder.class)
                    .eq(ProductThirdYcbdcUserOrder::getUserId,userId).orderByDesc(BaseDO::getCreateTime));
            if (CollUtil.isEmpty(list)){
                String mobile=RandomPhoneGenerator.newRandomPhone();
                //如果手机号重复，重新生成
                if (isMobileExist(mobile,userId)){
                    return null;
                }else {
                    ProductThirdYcbdcUserOrder order=new ProductThirdYcbdcUserOrder();
                    order.setUserId(userId);
                    order.setOrderId("0");
                    order.setSyncStatus(1);
                    order.setExpirationDate(null);
                    order.setMobile(mobile);
                    order.setSyncMsg("生成手机号");
                    order.setDataStatus(2);
                    order.setCreateUser(userId);
                    int i=productThirdYcbdcUserOrderDao.insert(order);
                    return mobile;
                }
            }else {
                return list.getFirst().getMobile();
            }
        } finally {
            // 释放分布式锁
            if (zLock != null) {
                distributedLock.unlock(zLock);
            }
        }

    }

    private boolean isMobileExist(String mobile, Long userId) {
        List<ProductThirdYcbdcUserOrder> list=productThirdYcbdcUserOrderDao.selectList(Wrappers.lambdaQuery(ProductThirdYcbdcUserOrder.class).ne(ProductThirdYcbdcUserOrder::getUserId,userId)
                .eq(ProductThirdYcbdcUserOrder::getMobile,mobile)
        );
        return CollUtil.isNotEmpty(list);
    }
}